const caseColModel = require('../models/caseCol.js');
const caseModel = require('../models/dubboCase.js');
const methodModel = require('../models/dubboMethod.js');
const dubboProjectModel = require('../models/dubboProject.js');
const baseController = require('./base.js');
const yapi = require('../yapi.js');
const _ = require('underscore');
// const Mock = require('mockjs');
// const Random = Mock.Random;

class caseColController extends baseController {
  constructor(ctx) {
    super(ctx);
    this.colModel = yapi.getInst(caseColModel);
    this.caseModel = yapi.getInst(caseModel);
    this.dubboProjectModel = yapi.getInst(dubboProjectModel);
    this.methodModel = yapi.getInst(methodModel);
  }

  /**
   * 获取所有接口集
   * @interface /case_col/list
   * @method GET
   * @category case_col
   * @foldnumber 10
   * @param {String} projectid email名称，不能为空
   * @returns {Object}
   * @example
   */
  async list(ctx) {
    try {
      let id = ctx.query.projectid;
      let dubboProject = await this.dubboProjectModel.getBaseInfo(id);
      if (dubboProject.projecttype === 'private') {
        if ((await this.checkAuth(dubboProject._id, 'dubboproject', 'view')) !== true) {
          return (ctx.body = yapi.commons.resReturn(null, 406, '没有权限'));
        }
      }
      let result = await this.colModel.list(id);
      result = result.sort((a, b) => {
        return a.index - b.index;
      });

      for (let i = 0; i < result.length; i++) {
        result[i] = result[i].toObject();
        let caseList = await this.caseModel.list(result[i]._id);

        for(let j=0; j< caseList.length; j++){
          let item = caseList[j].toObject();
          // let methodData = await this.methodModel.getBaseinfo(item.method_id);
          // item.path = methodData.path;
          caseList[j] = item;
        }

        caseList = caseList.sort((a, b) => {
          return a.index - b.index;
        });
        result[i].caseList = caseList;

      }
      ctx.body = yapi.commons.resReturn(result);
    } catch (e) {
      ctx.body = yapi.commons.resReturn(null, 402, e.message);
    }
  }

  /**
   * 增加测试实例集
   * @interface /case_col/add_col
   * @method POST
   * @category case_col
   * @foldnumber 10
   * @param {Number} projectid
   * @param {String} name
   * @param {String} desc
   * @returns {Object}
   * @example
   */

  async addCol(ctx) {
    try {
      let params = ctx.request.body;
      params = yapi.commons.handleParams(params, {
        name: 'string',
        projectid: 'number',
        desc: 'string'
      });

      if (!params.projectid) {
        return (ctx.body = yapi.commons.resReturn(null, 400, 'Dubbo项目id不能为空'));
      }
      if (!params.name) {
        return (ctx.body = yapi.commons.resReturn(null, 400, '集合名称不能为空'));
      }

      let auth = await this.checkAuth(params.projectid, 'dubboproject', 'edit');
      if (!auth) {
        return (ctx.body = yapi.commons.resReturn(null, 400, '没有权限'));
      }

      let result = await this.colModel.save({
        name: params.name,
        projectid: params.projectid,
        desc: params.desc,
        uid: this.getUid(),
        add_time: yapi.commons.time(),
        up_time: yapi.commons.time()
      });
      let username = this.getUsername();
      yapi.commons.saveLog({
        content: `<a href="/user/profile/${this.getUid()}">${username}</a> 添加了dubbo测试集 <a href="/dubboproject/${
          params.projectid
        }/interface/case_col/${result._id}">${params.name}</a>`,
        type: 'dubboproject',
        uid: this.getUid(),
        username: username,
        typeid: params.projectid
      });
      // this.projectModel.up(params.project_id,{up_time: new Date().getTime()}).then();
      ctx.body = yapi.commons.resReturn(result);
    } catch (e) {
      ctx.body = yapi.commons.resReturn(null, 402, e.message);
    }
  }

  /**
   * 获取一个接口集下的所有的测试用例
   * @interface /case_col/case_list
   * @method GET
   * @category case_col
   * @foldnumber 10
   * @param {String} col_id 接口集id
   * @returns {Object}
   * @example
   */
  async getCaseList(ctx) {
    try {
      let id = ctx.query.col_id;
      if (!id || id === 0) {
        return (ctx.body = yapi.commons.resReturn(null, 407, 'col_id不能为空'));
      }

      let colData = await this.colModel.get(id);
      let dubboProject = await this.dubboProjectModel.getBaseInfo(colData.projectid);

      if (dubboProject.projecttype === 'private') {
        if ((await this.checkAuth(dubboProject._id, 'dubboproject', 'view')) !== true) {
          return (ctx.body = yapi.commons.resReturn(null, 406, '没有权限'));
        }
      }

      ctx.body = await yapi.commons.getDubboCaseList(id);
    } catch (e) {
      ctx.body = yapi.commons.resReturn(null, 402, e.message);
    }
  }

  /**
   * 获取一个接口集下的所有的测试用例的环境变量
   * @interface /case_col/case_env_list
   * @method GET
   * @category case_col
   * @foldnumber 10
   * @param {String} col_id 接口集id
   * @returns {Object}
   * @example
   */
  async getCaseEnvList(ctx) {
    try {
      let id = ctx.query.col_id;
      if (!id || id === 0) {
        return (ctx.body = yapi.commons.resReturn(null, 407, 'col_id不能为空'));
      }

      let colData = await this.colModel.get(id);
      let dubboProject = await this.dubboProjectModel.getBaseInfo(colData.projectid);
      if (dubboProject.projecttype === 'private') {
        if ((await this.checkAuth(dubboProject._id, 'dubboproject', 'view')) !== true) {
          return (ctx.body = yapi.commons.resReturn(null, 406, '没有权限'));
        }
      }

      // 通过col_id 找到 caseList
      let dubboProjectList = await this.caseModel.list(id, 'projectid');
      // 对projectList 进行去重处理
      dubboProjectList = this.unique(dubboProjectList, 'projectid');

      // 遍历dubboProjectList 找到项目和env
      let dubboProjectEnvList = [];
      for (let i = 0; i < dubboProjectList.length; i++) {
        let result = await this.dubboProjectModel.getBaseInfo(dubboProjectList[i], 'cnname  evnconfig');
        dubboProjectEnvList.push(result);
      }
      ctx.body = yapi.commons.resReturn(dubboProjectEnvList);
    } catch (e) {
      ctx.body = yapi.commons.resReturn(null, 402, e.message);
    }
  }

  requestParamsToObj(arr) {
    if (!arr || !Array.isArray(arr) || arr.length === 0) {
      return {};
    }
    let obj = {};
    arr.forEach(item => {
      obj[item.name] = '';
    });
    return obj;
  }

  /**
   * 获取一个接口集下的所有的测试用例
   * @interface /case_col/case_list_by_var_params
   * @method GET
   * @category case_col
   * @foldnumber 10
   * @param {String} col_id 接口集id
   * @returns {Object}
   * @example
   */

  async getCaseListByVariableParams(ctx) {
    try {
      let id = ctx.query.col_id;
      if (!id || id == 0) {
        return (ctx.body = yapi.commons.resReturn(null, 407, 'col_id不能为空'));
      }
      let resultList = await this.caseModel.list(id, 'all');
      if (resultList.length === 0) {
        return (ctx.body = yapi.commons.resReturn([]));
      }
      let dubboProject = await this.dubboProjectModel.getBaseInfo(resultList[0].projectid);

      if (dubboProject.projecttype === 'private') {
        if ((await this.checkAuth(dubboProject._id, 'dubboproject', 'view')) !== true) {
          return (ctx.body = yapi.commons.resReturn(null, 406, '没有权限'));
        }
      }

      for (let index = 0; index < resultList.length; index++) {
        let result = resultList[index].toObject();
        let item = {},
          body,
          bodyParams;
        let data = await this.methodModel.get(result.method_id);
        if (!data) {
          await this.caseModel.del(result._id);
          continue;
        }
        item._id = result._id;
        item.casename = result.casename;
        // body = yapi.commons.json_parse(data.outbody);
        body = this.getRunJson(data.outbody);
        body = JSON.parse(body);
        body = typeof body === 'object' ? body : {};
        item.body = Object.assign({}, body);

        bodyParams = this.getRunJson(data.inbody);
        bodyParams = JSON.parse(bodyParams);
        bodyParams = typeof bodyParams === 'object' ? bodyParams : {};
        item.params = Object.assign(bodyParams);
        item.index = result.index;
        resultList[index] = item;
      }

      ctx.body = yapi.commons.resReturn(resultList);
    } catch (e) {
      ctx.body = yapi.commons.resReturn(null, 402, e.message);
    }
  }

  /**
   * 增加一个测试用例
   * @interface /case_col/add_case
   * @method POST
   * @category case_col
   * @foldnumber 10
   * @param {String} casename
   * @param {Number} col_id
   * @param {Number} project_id
   * @param {String} domain
   * @param {String} path
   * @param {String} method
   * @param {Object} req_query
   * @param {Object} req_headers
   * @param {String} req_body_type
   * @param {Array} req_body_form
   * @param {String} req_body_other
   * @returns {Object}
   * @example
   */

  async addCase(ctx) {
    try {
      let params = ctx.request.body;
      params = yapi.commons.handleParams(params, {
        casename: 'string',
        projectid: 'number',
        col_id: 'number',
        infid: 'number',
        method_id: 'number',
        case_env: 'string',
        isapi: 'number',
        url: 'string'
      });


      if (!params.projectid) {
        return (ctx.body = yapi.commons.resReturn(null, 400, 'Dubbo项目id不能为空'));
      }

      if (!params.method_id) {
        return (ctx.body = yapi.commons.resReturn(null, 400, '方法id不能为空'));
      }

      let auth = await this.checkAuth(params.projectid, 'dubboproject', 'edit');
      if (!auth) {
        return (ctx.body = yapi.commons.resReturn(null, 400, '没有权限'));
      }

      if (!params.col_id) {
        return (ctx.body = yapi.commons.resReturn(null, 400, '测试集id不能为空'));
      }

      if (!params.casename) {
        return (ctx.body = yapi.commons.resReturn(null, 400, '用例名称不能为空'));
      }

      let methodData = await this.methodModel.get(params.method_id);
      params.cname = methodData.cname;
      params.inname = methodData.inname;
      params.isapi = methodData.isapi;
      params.url = methodData.url;
      params.cuserid = this.getUid();
      // params.index = 0;
      params.ctime = yapi.commons.time();
      params.etime = yapi.commons.time();
      let result = await this.caseModel.save(params);
      let username = this.getUsername();

      this.colModel.get(params.col_id).then(col => {
        yapi.commons.saveLog({
          content: `<a href="/user/profile/${this.getUid()}">${username}</a> 在测试集 <a href="/dubboproject/${
            params.projectid
          }/interface/case_col/${params.col_id}">${col.name}</a> 下添加了测试用例 <a href="/dubboproject/${
            params.projectid
          }/interface/case/${result._id}">${params.casename}</a>`,
          type: 'dubboproject',
          uid: this.getUid(),
          username: username,
          typeid: params.projectid
        });
      });
      this.dubboProjectModel.up(params.projectid, { up_time: new Date().getTime() }).then();

      ctx.body = yapi.commons.resReturn(result);
    } catch (e) {
      ctx.body = yapi.commons.resReturn(null, 402, e.message);
    }
  }

  async addCaseList(ctx) {
    try {
      let params = ctx.request.body;
      params = yapi.commons.handleParams(params, {
        projectid: 'number',
        col_id: 'number'
      });
      if (!params.method_list || !Array.isArray(params.method_list)) {
        return (ctx.body = yapi.commons.resReturn(null, 400, 'interface_list 参数有误'));
      }

      if (!params.projectid) {
        return (ctx.body = yapi.commons.resReturn(null, 400, 'Dubbo项目id不能为空'));
      }

      let auth = await this.checkAuth(params.projectid, 'dubboproject', 'edit');
      if (!auth) {
        return (ctx.body = yapi.commons.resReturn(null, 400, '没有权限'));
      }

      if (!params.col_id) {
        return (ctx.body = yapi.commons.resReturn(null, 400, '测试集id不能为空'));
      }

      let data = {
        cuserid: this.getUid(),
        // index: 0,
        ctime: yapi.commons.time(),
        etime: yapi.commons.time(),
        projectid: params.projectid,
        col_id: params.col_id
      };

      for (let i = 0; i < params.method_list.length; i++) {
        let methodData = await this.methodModel.get(params.method_list[i]);
        data.method_id = params.method_list[i];
        data.cname = methodData.cname;
        data.casename = methodData.mname;
        data.infid = methodData.infid;
        data.inname = methodData.inname;
        data.outname = methodData.outname;
        data.outbody = methodData.outbody;
        data.isapi = methodData.isapi;
        data.url = methodData.url;

        // 处理json schema 解析
        let result;
        if (methodData.inbody) {
          result = this.getRunJson(methodData.inbody);
          data.inbody = result;
        } else {
          data.inbody = methodData.inbody;
        }
        let caseResultData = await this.caseModel.save(data);
        let username = this.getUsername();
        this.colModel.get(params.col_id).then(col => {
          yapi.commons.saveLog({
            content: `<a href="/user/profile/${this.getUid()}">${username}</a> 在测试集 <a href="/dubboproject/${
              params.projectid
            }/interface/case_col/${params.col_id}">${col.name}</a> 下导入了测试用例 <a href="/dubboproject/${
              params.projectid
            }/interface/case/${caseResultData._id}">${data.casename}</a>`,
            type: 'dubboproject',
            uid: this.getUid(),
            username: username,
            typeid: params.projectid
          });
        });
      }

      this.dubboProjectModel.up(params.projectid, { up_time: new Date().getTime() }).then();

      ctx.body = yapi.commons.resReturn('ok');
    } catch (e) {
      ctx.body = yapi.commons.resReturn(null, 402, e.message);
    }
  }

  async cloneCaseList(ctx) {
    try {
      let params = ctx.request.body;
      params = yapi.commons.handleParams(params, {
        projectid: 'number',
        col_id: 'number',
        new_col_id: 'number'
      });

      const { projectid, col_id, new_col_id } = params;

      if (!projectid) {
        return (ctx.body = yapi.commons.resReturn(null, 400, 'Dubbo项目id不能为空'));
      }

      let auth = await this.checkAuth(params.projectid, 'dubboproject', 'edit');
      if (!auth) {
        return (ctx.body = yapi.commons.resReturn(null, 400, '没有权限'));
      }

      if (!col_id) {
        return (ctx.body = yapi.commons.resReturn(null, 400, '被克隆的接口集id不能为空'));
      }

      if (!new_col_id) {
        return (ctx.body = yapi.commons.resReturn(null, 400, '克隆的接口集id不能为空'));
      }

      let oldColCaselistData = await this.caseModel.list(col_id, 'all');

      oldColCaselistData = oldColCaselistData.sort((a, b) => {
        return a.index - b.index;
      });

      const newCaseList = [];
      const oldCaseObj = {};
      let obj = {};

      const handleTypeParams = (data, name) => {
        let res = data[name];
        const type = Object.prototype.toString.call(res);
        if (type === '[object Array]' && res.length) {
          res = JSON.stringify(res);
          try {
            res = JSON.parse(handleReplaceStr(res));
          } catch (e) {
            console.log('e ->', e);
          }
        } else if (type === '[object String]' && data[name]) {
          res = handleReplaceStr(res);
        }
        return res;
      };

      const handleReplaceStr = str => {
        if (str.indexOf('$') !== -1) {
          str = str.replace(/\$\.([0-9]+)\./g, function(match, p1) {
            p1 = p1.toString();
            return `$.${newCaseList[oldCaseObj[p1]]}.` || '';
          });
        }
        return str;
      };

      // 处理数据里面的$id;
      const handleParams = data => {
        data.col_id = new_col_id;
        delete data._id;
        delete data.add_time;
        delete data.up_time;
        delete data.__v;
        data.req_body_other = handleTypeParams(data, 'req_body_other');
        data.req_query = handleTypeParams(data, 'req_query');
        data.req_params = handleTypeParams(data, 'req_params');
        data.req_body_form = handleTypeParams(data, 'req_body_form');
        return data;
      };

      for (let i = 0; i < oldColCaselistData.length; i++) {
        obj = oldColCaselistData[i].toObject();
        // 将被克隆的id和位置绑定
        oldCaseObj[obj._id] = i;
        let caseData = handleParams(obj);
        caseData.cuserid = this.getUid();
        let newCase = await this.caseModel.save(caseData);
        newCaseList.push(newCase._id);
      }

      this.dubboProjectModel.up(params.projectid, { up_time: new Date().getTime() }).then();
      ctx.body = yapi.commons.resReturn('ok');
    } catch (e) {
      ctx.body = yapi.commons.resReturn(null, 402, e.message);
    }
  }

  /**
   * 更新一个测试用例
   * @interface /case_col/up_case
   * @method POST
   * @category case_col
   * @foldnumber 10
   * @param {number} id
   * @param {String} casename
   * @param {String} domain
   * @param {String} path
   * @param {String} method
   * @param {Object} req_query
   * @param {Object} req_headers
   * @param {String} req_body_type
   * @param {Array} req_body_form
   * @param {String} req_body_other
   * @returns {Object}
   * @example
   */

  async upCase(ctx) {
    try {
      let params = ctx.request.body;
      params = yapi.commons.handleParams(params, {
        id: 'number',
        casename: 'string'
      });

      if (!params.id) {
        return (ctx.body = yapi.commons.resReturn(null, 400, '用例id不能为空'));
      }

      // if (!params.casename) {
      //   return (ctx.body = yapi.commons.resReturn(null, 400, '用例名称不能为空'));
      // }

      let caseData = await this.caseModel.get(params.id);
      let auth = await this.checkAuth(caseData.projectid, 'dubboproject', 'edit');
      if (!auth) {
        return (ctx.body = yapi.commons.resReturn(null, 400, '没有权限'));
      }

      params.euserid = this.getUid();

      //不允许修改接口id和项目id
      delete params.infid;
      delete params.projectid;
      let result = await this.caseModel.up(params.id, params);
      let username = this.getUsername();
      this.colModel.get(caseData.col_id).then(col => {
        yapi.commons.saveLog({
          content: `<a href="/user/profile/${this.getUid()}">${username}</a> 在测试集 <a href="/dubboproject/${
            caseData.projectid
          }/interface/case_col/${caseData.col_id}">${col.name}</a> 更新了测试用例 <a href="/dubboproject/${
            caseData.projectid
          }/interface/case/${params.id}">${params.casename || caseData.casename}</a>`,
          type: 'dubboproject',
          uid: this.getUid(),
          username: username,
          typeid: caseData.projectid
        });
      });

      this.dubboProjectModel.up(caseData.projectid, { up_time: new Date().getTime() }).then();

      ctx.body = yapi.commons.resReturn(result);
    } catch (e) {
      ctx.body = yapi.commons.resReturn(null, 402, e.message);
    }
  }

  /**
   * 获取一个测试用例详情
   * @interface /case_col/case
   * @method GET
   * @category case_col
   * @foldnumber 10
   * @param {String} caseid
   * @returns {Object}
   * @example
   */

  async getCase(ctx) {
    try {
      let id = ctx.query.caseid;
      let result = await this.caseModel.get(id);
      if (!result) {
        return (ctx.body = yapi.commons.resReturn(null, 400, '不存在的case'));
      }
      result = result.toObject();
      let data = await this.methodModel.get(result.method_id);
      if (!data) {
        return (ctx.body = yapi.commons.resReturn(null, 400, '找不到对应的方法，请联系管理员'));
      }
      data = data.toObject();
      // 用户测试用例中的“对应接口”
      // let projectData = await this.dubboProjectModel.getBaseInfo(data.projectid);
      // result.path = projectData.basepath + data.path;
      result.method_up_time = data.etime;
      result.etime = data.etime;
      ctx.body = yapi.commons.resReturn(result);
    } catch (e) {
      ctx.body = yapi.commons.resReturn(null, 400, e.message);
    }
  }

  /**
   * 更新一个接口集name或描述
   * @interface /col/up_col
   * @method POST
   * @category col
   * @foldnumber 10
   * @param {String} name
   * @param {String} desc
   * @returns {Object}
   * @example
   */

  async upCol(ctx) {
    try {
      let params = ctx.request.body;
      let id = params.col_id;
      if (!id) {
        return (ctx.body = yapi.commons.resReturn(null, 400, '缺少 col_id 参数'));
      }
      let colData = await this.colModel.get(id);
      if (!colData) {
        return (ctx.body = yapi.commons.resReturn(null, 400, '不存在'));
      }
      let auth = await this.checkAuth(colData.project_id, 'project', 'edit');
      if (!auth) {
        return (ctx.body = yapi.commons.resReturn(null, 400, '没有权限'));
      }
      delete params.col_id;
      let result = await this.colModel.up(id, params);
      let username = this.getUsername();
      yapi.commons.saveLog({
        content: `<a href="/user/profile/${this.getUid()}">${username}</a> 更新了测试集合 <a href="/project/${
          colData.project_id
        }/interface/col/${id}">${colData.name}</a> 的信息`,
        type: 'project',
        uid: this.getUid(),
        username: username,
        typeid: colData.project_id
      });

      ctx.body = yapi.commons.resReturn(result);
    } catch (e) {
      ctx.body = yapi.commons.resReturn(null, 400, e.message);
    }
  }

  /**
   * 更新多个接口case index
   * @interface /col/up_case_index
   * @method POST
   * @category col
   * @foldnumber 10
   * @param {Array}  [id, index]
   * @returns {Object}
   * @example
   */

  async upCaseIndex(ctx) {
    try {
      let params = ctx.request.body;
      if (!params || !Array.isArray(params)) {
        ctx.body = yapi.commons.resReturn(null, 400, '请求参数必须是数组');
      }
      params.forEach(item => {
        if (item.id) {
          this.caseModel.upCaseIndex(item.id, item.index).then(
            res => {},
            err => {
              yapi.commons.log(err.message, 'error');
            }
          );
        }
      });

      return (ctx.body = yapi.commons.resReturn('成功！'));
    } catch (e) {
      ctx.body = yapi.commons.resReturn(null, 400, e.message);
    }
  }

  /**
   * 更新多个测试集合 index
   * @interface /col/up_col_index
   * @method POST
   * @category col
   * @foldnumber 10
   * @param {Array}  [id, index]
   * @returns {Object}
   * @example
   */

  async upColIndex(ctx) {
    try {
      let params = ctx.request.body;
      if (!params || !Array.isArray(params)) {
        ctx.body = yapi.commons.resReturn(null, 400, '请求参数必须是数组');
      }
      params.forEach(item => {
        if (item.id) {
          this.colModel.upColIndex(item.id, item.index).then(
            res => {},
            err => {
              yapi.commons.log(err.message, 'error');
            }
          );
        }
      });

      return (ctx.body = yapi.commons.resReturn('成功！'));
    } catch (e) {
      ctx.body = yapi.commons.resReturn(null, 400, e.message);
    }
  }

  /**
   * 删除一个接口集
   * @interface /col/del_col
   * @method GET
   * @category col
   * @foldnumber 10
   * @param {String}
   * @returns {Object}
   * @example
   */

  async delCol(ctx) {
    try {
      let id = ctx.query.col_id;
      let colData = await this.colModel.get(id);
      if (!colData) {
        ctx.body = yapi.commons.resReturn(null, 400, '不存在的id');
      }

      if (colData.uid !== this.getUid()) {
        let auth = await this.checkAuth(colData.projectid, 'dubboproject', 'danger');
        if (!auth) {
          return (ctx.body = yapi.commons.resReturn(null, 400, '没有权限'));
        }
      }
      let result = await this.colModel.del(id);
      await this.caseModel.delByCol(id);
      let username = this.getUsername();
      yapi.commons.saveLog({
        content: `<a href="/user/profile/${this.getUid()}">${username}</a> 删除了测试集 ${
          colData.name
        } 及其下面的接口`,
        type: 'dubboproject',
        uid: this.getUid(),
        username: username,
        typeid: colData.projectid
      });
      return (ctx.body = yapi.commons.resReturn(result));
    } catch (e) {
      yapi.commons.resReturn(null, 400, e.message);
    }
  }

  /**
   *
   * @param {*} ctx
   */

  async delCase(ctx) {
    try {
      let caseid = ctx.query.caseid;
      let caseData = await this.caseModel.get(caseid);
      if (!caseData) {
        ctx.body = yapi.commons.resReturn(null, 400, '不存在的caseid');
      }

      if (caseData.cuserid !== this.getUid()) {
        let auth = await this.checkAuth(caseData.projectid, 'dubboproject', 'danger');
        if (!auth) {
          return (ctx.body = yapi.commons.resReturn(null, 400, '没有权限'));
        }
      }

      let result = await this.caseModel.del(caseid);

      let username = this.getUsername();
      this.colModel.get(caseData.col_id).then(col => {
        yapi.commons.saveLog({
          content: `<a href="/user/profile/${this.getUid()}">${username}</a> 删除了测试集 <a href="/dubboproject/${
            caseData.projectid
          }/interface/case_col/${caseData.col_id}">${col.name}</a> 下的接口 ${caseData.casename}`,
          type: 'dubboproject',
          uid: this.getUid(),
          username: username,
          typeid: caseData.projectid
        });
      });

      this.dubboProjectModel.up(caseData.projectid, { up_time: new Date().getTime() }).then();
      return (ctx.body = yapi.commons.resReturn(result));
    } catch (e) {
      yapi.commons.resReturn(null, 400, e.message);
    }
  }

  async runDubboCaseScript(ctx) {
    let params = ctx.request.body;
    ctx.body = await yapi.commons.runDubboCaseScript(params, params.col_id, params.method_id, this.getUid());
  }

  // 数组去重
  unique(array, compare) {
    let hash = {};
    let arr = array.reduce(function(item, next) {
      hash[next[compare]] ? '' : (hash[next[compare]] = item.push(next));
      // console.log('item',item.project_id)
      return item;
    }, []);
    // 输出去重以后的project_id
    return arr.map(item => {
      return item[compare];
    });
  }

  jsonToBody(str){
    if (typeof(str) === 'object') {
      return str;
    }
    const reviver = (index, value) => {
      // 去除undefined 和 null
      if (value === undefined){
        return undefined;
      }
      return value;
    };
    return JSON.parse(str, reviver);
  }

    /**
     * 转化database存储的json为run运行需要的json
     * @param str: 需要转换的字符串
     * @param useRandom: 是否生成随机数据, defaultValue = false
     * @param useDefault: 仅在useRamdom = false 下生效, 是否使用default值, defaultValue = true
     * @param listLength: list长度, 为false时代表使用随机长度 defaultVaue = 2
     * @param listUseDefault: 仅在useDefault = true 下生效, list对象是否使用default值, defaultValue = true
     * @param objectUseDefault: 仅在useDefault = true 下生效, object对象是否使用default值, defaultValue = true
     * @returns {string}
     */
  getRunJson(str, useRandom, useDefault, listLength, listUseDefault, objectUseDefault){
      listLength = listLength === undefined ? 2 : listLength;
      useRandom = useRandom === undefined ? false : true;
      useDefault = useDefault === undefined ? true : false;
      listUseDefault = listUseDefault === undefined ? true : false;
      objectUseDefault = objectUseDefault === undefined ? true : false;

    if (str === undefined) {
      return;
    }
    if (!(typeof(str) === 'string')) {
      return;
    }
    let ret = '';
    const getRandomLength = (minLength, maxLength) => {
      minLength = minLength === undefined ? 1 : minLength;
      maxLength = maxLength === undefined ? minLength + 9 : maxLength;
      return parseInt(Math.random() * (maxLength - minLength + 1) + minLength, 10)
    };
    // 获取随机数据
    const getRandomData = (type, length) => {
      const getRandomStr = (length) => {
        function randomWord(randomFlag, min, max) {
          let str = "",
              range = min,
              arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
                'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
                'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
                'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];

          if (randomFlag) {
            range = Math.round(Math.random() * (max - min)) + min;// 任意长度
          }
          for (let i = 0; i < range; i++) {
            let pos = Math.round(Math.random() * (arr.length - 1));
            str += arr[pos];
          }
          return str;
        }
        let ret;
        length = length === undefined ? getRandomLength(15, 30) : length;
        ret = '' + randomWord(false, length, length);
        return ret
      };
      // 这里规定为有符号整型 十进制, length为十进制长度, length不包括符号
      // length会自动转化成绝对值
      const getRandomInt = (length) => {
        let ret;
        length = length === undefined ? getRandomLength() : length;
        length = Math.abs(length);
        let max = 10 * length;
        ret = Math.floor(Math.random() * (max + 1));
        if(Math.round(Math.random())) {
          ret = -ret
        }
        return ret
      };
      // 当前length为小数长度, 会取绝对值
      const getRandomBigDecimal = (length) => {
        let ret;
        let max = 9999999; // 整数最大值
        length = length === undefined ? 10 : length;
        length = parseInt(Math.abs(length));
        ret = Math.random();
        ret = ret.toFixed(length) + Math.floor(Math.random() * (max + 1));
        if(Math.round(Math.random())) {
          ret = -ret
        }
        return ret
      };
      const mapper = {
        'String': getRandomStr,
        'Integer': getRandomInt,
        'BigDecimal': getRandomBigDecimal
      };
      ret = mapper[type](length);
      return ret;
    };
    // body 必须是一个object类型
    const process = (body) => {
      const field_type = body.field_type;
      if(field_type === 'String' || field_type === 'Integer' || field_type === 'BigDecimal') {
          return useRandom ? getRandomData(field_type, body.length) : (
              useDefault ? (body.default === undefined ? null : body.default) : null
          );
      } else if(field_type === 'List') {
          if (useDefault && listUseDefault) {
              if (body.default === undefined) {
              } else {
                  return body.default
              }
          }
        // 无论用户定义什么自定义类型，它肯定是一个object
        let temp_length = body.children[0].length === undefined ?
            (listLength === false ? getRandomLength() : listLength) : body.children[0].length;
        let temp_body = [];
        for(var i = 0; i < temp_length; i++) {
          temp_body.push(process(body.children[0]))
        }
        return temp_body;
      } else if (field_type === 'Object') {
          if (useDefault && objectUseDefault) {
              if (body.default === undefined) {
              } else {
                  return body.default
              }
          }
        let temp_body = {};
        body.children.map((value) => {
          temp_body[value.name] = process(value)
        });
        return temp_body
      }
    };
    // 获取含有随机数据的object或array
    // body必须是一个数组
    const getBodyWithRandom = (body) => {
      let ret = {};
      body.map((value) => {
        ret[value.name] = process(value)
      });
      return ret
    };
    ret = this.jsonToBody(str);
    ret = getBodyWithRandom(ret);
    ret = JSON.stringify(ret, 2);
    return ret;
  }
}

module.exports = caseColController;
